<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Sentinel node</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Sentinel_node"> <link href="./mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Sentinel_node rootpage-Sentinel_node skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Sentinel node</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1236090951">
/* start https://en.wikipedia.org/ */
.mw-parser-output .hatnote{font-style:italic}.mw-parser-output div.hatnote{padding-left:1.6em;margin-bottom:0.5em}.mw-parser-output .hatnote i{font-style:normal}.mw-parser-output .hatnote+link+.hatnote{margin-top:-0.5em}@media print{body.ns-0 .mw-parser-output .hatnote{display:none!important}}
/* end https://en.wikipedia.org/ */
</style><div role="note" class="hatnote navigation-not-searchable">This article is about the computer programming construct. For the body part, see <a href="Sentinel_lymph_node" title="Sentinel lymph node">Sentinel lymph node</a>.</div>
<div role="note" class="hatnote navigation-not-searchable">Not to be confused with <a href="Sentinel_value" title="Sentinel value">sentinel value</a>.</div>
<style data-mw-deduplicate="TemplateStyles:r1251242444">
/* start https://en.wikipedia.org/ */
.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style>
<p>In computer programming, a <b>sentinel node</b> is a specifically designated <a href="Node_(computer_science)" title="Node (computer science)">node</a> used with <a href="Linked_list" title="Linked list">linked lists</a> and <a href="Tree_(data_structure)" class="mw-redirect" title="Tree (data structure)">trees</a> as a traversal path terminator. This type of node does not hold or reference any data managed by the data structure.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Benefits">Benefits</h2></div>
<p>Sentinels are used as an alternative over using <a href="Null_pointer" title="Null pointer"><code>NULL</code></a> as the path terminator in order to get one or more of the following benefits:
</p>
<ul><li>Marginally increased speed of operations</li>
<li>Increased data structure <a href="Robustness_(computer_science)" title="Robustness (computer science)">robustness</a> (arguably)</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Drawbacks">Drawbacks</h2></div>
<ul><li>Marginally increased memory usage, especially when linked list is short.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Examples">Examples</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Search_in_a_linked_list">Search in a linked list</h3></div>
<p>Below are two versions of a subroutine (implemented in the <a href="C_(programming_language)" title="C (programming language)">C programming language</a>) for looking up a given search key in a <a href="Linked_list#Singly_linked_list" title="Linked list">singly linked list</a>. The first one uses the <a href="Sentinel_value" title="Sentinel value">sentinel value</a> <code>NULL</code>, and the second one a (pointer to the) sentinel node <code>Sentinel</code>, as the end-of-list indicator. The declarations of the singly linked list data structure and the outcomes of both subroutines are the same.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// one node of the singly linked list</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">next</span><span class="p">;</span><span class="w"> </span><span class="c1">// end-of-list indicator or -> next node</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="n">sll</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">first</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="First_version_using_NULL_as_an_end-of-list_indicator">First version using NULL as an end-of-list indicator</h4></div>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="c1">// global initialization</span>
<span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"> </span><span class="c1">// before the first insertion (not shown)</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">Search</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">search_key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="p">;</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">first</span><span class="p">;</span><span class="w"> </span>
<span class="hll"><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span><span class="w"> </span>
</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">next</span><span class="p">)</span>
<span class="w"> </span><span class="p">{</span>
<span class="hll"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="o">-></span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">search_key</span><span class="p">)</span>
</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">node</span><span class="p">;</span><span class="w"> </span><span class="c1">// found</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="c1">// search_key is not contained in the list:</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>The <code>for</code>-loop contains two tests (yellow lines) per iteration:
</p>
<ul><li><code>node != NULL;</code></li>
<li><code>if (node->key == search_key)</code>.</li></ul>
<div class="mw-heading mw-heading4"><h4 id="Second_version_using_a_sentinel_node">Second version using a sentinel node</h4></div>
<p>The globally available pointer <code>sentinel</code> to the deliberately prepared data structure <code>Sentinel</code> is used as end-of-list indicator.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="c1">// global variable</span>
<span class="n">sll_node</span><span class="w"> </span><span class="n">Sentinel</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">sentinel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">Sentinel</span><span class="p">;</span>
<span class="c1">// global initialization</span>
<span class="n">sentinel</span><span class="o">-></span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">;</span>
<span class="n">first</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">;</span><span class="w"> </span><span class="c1">// before the first insertion (not shown)</span>
</pre></div>
<p>Note that the <i>pointer</i> sentinel has always to be kept at the end of the list.
This has to be maintained by the insert and delete functions. It is, however, about the same effort as when using a NULL pointer.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">SearchWithSentinelnode</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">first</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">search_key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">sll_node</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// Prepare the “node” Sentinel for the search:</span>
<span class="w"> </span><span class="n">sentinel</span><span class="o">-></span><span class="n">key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">search_key</span><span class="p">;</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">first</span><span class="p">;</span><span class="w"> </span>
<span class="hll"><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">key</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">search_key</span><span class="p">;</span><span class="w"> </span>
</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">next</span><span class="p">)</span>
<span class="w"> </span><span class="p">{}</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// Post-processing:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">)</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">node</span><span class="p">;</span><span class="w"> </span><span class="c1">// found</span>
<span class="w"> </span><span class="c1">// search_key is not contained in the list:</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>The <code>for</code>-loop contains only one test (yellow line) per iteration:
</p>
<ul><li><code>node->key != search_key;</code>.</li></ul>
<div class="mw-heading mw-heading4"><h4 id="Python_implementation_of_a_circular_doubly-linked_list">Python implementation of a circular doubly-linked list</h4></div>
<p>Linked list implementations, especially one of a circular, doubly-linked list, can be simplified remarkably using a sentinel node to demarcate the beginning and end of the list.
</p>
<ul><li>The list starts out with a single node, the sentinel node which has the next and previous pointers point to itself. This condition determines if the list is empty.</li>
<li>In a non-empty list, the sentinel node's next pointer gives the head of the list, and the previous pointer gives the tail of the list.</li></ul>
<p>Following is a Python implementation of a circular doubly-linked list:
</p>
<div class="mw-highlight mw-highlight-lang-python mw-content-ltr" dir="ltr"><pre><span class="k">class</span> <span class="nc">Node</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="nb">next</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">prev</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
<span class="bp">self</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">next</span>
<span class="bp">self</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">prev</span>
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
<span class="k">return</span> <span class="sa">f</span><span class="s1">'Node(data=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="si">}</span><span class="s1">)'</span>
<span class="k">class</span> <span class="nc">LinkedList</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span>
<span class="k">def</span> <span class="nf">pop_left</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Node</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">remove_by_ref</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">next</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Node</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">remove_by_ref</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">prev</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">append_nodeleft</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_node</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="p">,</span> <span class="n">node</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">append_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add_node</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">prev</span><span class="p">,</span> <span class="n">node</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">append_left</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">append_nodeleft</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">data</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">append_node</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">remove_by_ref</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">)</span> <span class="o">-></span> <span class="n">Node</span><span class="p">:</span>
<span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'Can never remove sentinel.'</span><span class="p">)</span>
<span class="n">node</span><span class="o">.</span><span class="n">prev</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">next</span>
<span class="n">node</span><span class="o">.</span><span class="n">next</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">prev</span>
<span class="n">node</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">node</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">node</span>
<span class="k">def</span> <span class="nf">add_node</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">curnode</span><span class="p">,</span> <span class="n">newnode</span><span class="p">):</span>
<span class="n">newnode</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">curnode</span><span class="o">.</span><span class="n">next</span>
<span class="n">newnode</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">curnode</span>
<span class="n">curnode</span><span class="o">.</span><span class="n">next</span><span class="o">.</span><span class="n">prev</span> <span class="o">=</span> <span class="n">newnode</span>
<span class="n">curnode</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">newnode</span>
<span class="k">def</span> <span class="nf">search</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">value</span>
<span class="n">node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">next</span>
<span class="k">while</span> <span class="n">node</span><span class="o">.</span><span class="n">data</span> <span class="o">!=</span> <span class="n">value</span><span class="p">:</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">next</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">None</span>
<span class="k">return</span> <span class="n">node</span>
<span class="k">def</span> <span class="fm">__iter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">next</span>
<span class="k">while</span> <span class="n">node</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">node</span><span class="o">.</span><span class="n">data</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">next</span>
<span class="k">def</span> <span class="nf">reviter</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="o">.</span><span class="n">prev</span>
<span class="k">while</span> <span class="n">node</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sentinel</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">node</span><span class="o">.</span><span class="n">data</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">prev</span>
</pre></div>
<p>Notice how the <code>add_node()</code> method takes the node that will be displaced by the new node in the parameter <code>curnode</code>. For appending to the left, this is the head of a non-empty list, while for appending to right, it is the tail. But because of how the linkage is set up to refer back to the sentinel, the code just works for empty lists as well, where <code>curnode</code> will be the sentinel node.
</p>
<div class="mw-heading mw-heading3"><h3 id="Search_in_a_binary_tree">Search in a binary tree</h3></div>
<p>General declarations, similar to article <a href="Binary_search_tree" title="Binary search tree">Binary search tree</a>:
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="k">struct</span><span class="w"> </span><span class="nc">bst_node</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// one node of the binary search tree</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">bst_node</span><span class="w"> </span><span class="o">*</span><span class="n">child</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span><span class="w"> </span><span class="c1">// each: ->node or end-of-path indicator</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">;</span>
<span class="p">}</span><span class="w"> </span><span class="p">;</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">bst</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// binary search tree</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">bst_node</span><span class="w"> </span><span class="o">*</span><span class="n">root</span><span class="p">;</span><span class="w"> </span><span class="c1">// ->node or end-of-path indicator</span>
<span class="p">}</span><span class="w"> </span><span class="o">*</span><span class="n">BST</span><span class="p">;</span>
</pre></div>
<p>The globally available <i>pointer</i> <code>sentinel</code> to the <i>single</i> deliberately prepared data structure <code>Sentinel = *sentinel</code> is used to indicate the absence of a child.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="c1">// global variable</span>
<span class="n">bst_node</span><span class="w"> </span><span class="n">Sentinel</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">sentinel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&</span><span class="n">Sentinel</span><span class="p">;</span>
<span class="c1">// global initialization</span>
<span class="n">Sentinel</span><span class="p">.</span><span class="n">child</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Sentinel</span><span class="p">.</span><span class="n">child</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">;</span>
<span class="n">BST</span><span class="o">-></span><span class="n">root</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">;</span><span class="w"> </span><span class="c1">// before the first insertion (not shown)</span>
</pre></div>
<p>Note that the <i>pointer</i> sentinel has always to represent every leaf of the tree.
This has to be maintained by the insert and delete functions. It is, however, about the same effort as when using a NULL pointer.
</p>
<div class="mw-highlight mw-highlight-lang-c mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">struct</span><span class="w"> </span><span class="nc">bst_node</span><span class="w"> </span><span class="o">*</span><span class="n">SearchWithSentinelnode</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">bst</span><span class="w"> </span><span class="o">*</span><span class="n">bst</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">search_key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">bst_node</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// Prepare the “node” Sentinel for the search:</span>
<span class="w"> </span><span class="n">sentinel</span><span class="o">-></span><span class="n">key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">search_key</span><span class="p">;</span>
<span class="w"> </span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">bst</span><span class="o">-></span><span class="n">root</span><span class="p">;;)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">search_key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">key</span><span class="p">)</span>
<span class="w"> </span><span class="k">break</span><span class="p">;</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">search_key</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">key</span><span class="o">:</span>
<span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">child</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span><span class="w"> </span><span class="c1">// go left</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="o">-></span><span class="n">child</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// go right</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span>
<span class="w"> </span><span class="c1">// Post-processing:</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">sentinel</span><span class="p">)</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">node</span><span class="p">;</span><span class="w"> </span><span class="c1">// found</span>
<span class="w"> </span><span class="c1">// search_key is not contained in the tree:</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<dl><dt>Remarks</dt>
<dd></dd></dl>
<ol><li>With the use of SearchWithSentinelnode searching loses the <a href="File-system_permissions" title="File-system permissions">read-only</a> property. This means that in applications with <a href="Concurrent_computing" title="Concurrent computing">concurrency</a> it has to be protected by a <a href="Mutex" class="mw-redirect" title="Mutex">mutex</a>, an effort which normally exceeds the savings of the sentinel.</li>
<li>SearchWithSentinelnode does not support the tolerance of duplicates.</li>
<li>There has to be exactly one “node” to be used as sentinel, but there may be extremely many pointers to it.</li></ol>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<ul><li><a href="Canary_value" class="mw-redirect" title="Canary value">Canary value</a></li>
<li><a href="Elephant_in_Cairo" title="Elephant in Cairo">Elephant in Cairo</a></li>
<li><a href="Guard_(computer_science)" title="Guard (computer science)">Guard (computer science)</a>, a boolean expression that must evaluate to true if the program execution is to continue in the branch in question</li>
<li><a href="Magic_number_(programming)" title="Magic number (programming)">Magic number (programming)</a></li>
<li><a href="Magic_string" title="Magic string">Magic string</a></li>
<li><a href="Null_object_pattern" title="Null object pattern">Null object pattern</a></li>
<li><a href="Semipredicate_problem" title="Semipredicate problem">Semipredicate problem</a></li>
<li><a href="Sentinel_value" title="Sentinel value">Sentinel value</a></li>
<li><a href="Time_formatting_and_storage_bugs" title="Time formatting and storage bugs">Time formatting and storage bugs</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
</div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2024-09-25" href="https://en.wikipedia.org/wiki/?title=Sentinel_node&oldid=1247715853">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>